/*  Copyright 2010 Daniel Brasil Magnani
 *  Created on: Dec 20, 2010
 *      Author: daniel
 */

#ifndef CSP_SOLUTION_H_
#define CSP_SOLUTION_H_

#include <algorithm>
#include <vector>
#include "chronometer.h"
#include "instance.h"

class Solution {
 public:
  // Get method for the solution.
  std::vector<Car> get_solution();
  // Initialize the solution
  Solution(const std::vector<Car> &solution);
  // Execute the swap local search with first choice
  int LocalSearch(float time_limit);
 private:
  std::vector<std::vector<int> > M1_;
  std::vector<std::vector<int> > M2_;
  std::vector<std::vector<int> > M3_;
  std::vector<std::vector<int> > M4_;
  std::vector<std::vector<int> > M5_;
  std::vector<std::vector<int> > M6_;
  std::vector<std::vector<int> > M7_;
  int *map_;
  std::vector<int*> max_profit_;
  std::vector<Car> solution_;
  int solution_size_;
  int constraint_size_;
  int yesterday_size_;

  // Update M1, M2 and M3
  void UpdateStructures();
  // Retrieve the variation of violations of the insertion of car c in position
  // i for the constraint k.
  int InsertCost(int i, int j, int k);
  // Retrieve the variation of violations of the removal of the car in position
  // i for the constraint k.
  int RemoveCost(int i, int j, int k);
  // Retrieve the variation of violations of the swap of the car in position
  // i for j, within the constraint k.
  int SwapVariation(int i, int j, int k);
  // Retrieve the cost of the swap operation between cars i and j for the
  // constraint k
  int SwapCost(int i, int j, int k);
  // Retrieve the cost of the insertion operations between cars i and j for the
  // constraint k
  void Swap(int i, int j);
  int InsertionCost(int i, int j, int k);
  void Insertion(int i, int j);
  int ReflectionCost(int i, int j, int k);
  void Reflection(int i, int j);
  int ShuffleCost(int i, int j, int k);
  void Shuffle(int i, int j);

  int ChooseTransformation(int random);
  void CreateMap(int i, int j);
  int TransformationCost(int transformation, int i, int j, int k);
  void Transformation(int transformation, int i, int j);
  int ChooseVariant(int random);
  void GetCars(int* cars, int variant);

};

#endif  // CSP_SOLUTION_H_
